1. add csv_util.c and csv_util.h
authorrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Wed, 18 Sep 2002 14:41:41 +0000 (14:41 +0000)
committerrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Wed, 18 Sep 2002 14:41:41 +0000 (14:41 +0000)
2.  change mxf.c to use csv_util / minor other changes
3.  change csv to use csv_util
4.  add OziExplorer 1.1 file format.
5.  remove the extra MXF section from the README

Thanks,

Alex

gpsbabel/csv_util.c [new file with mode: 0644]
gpsbabel/csv_util.h [new file with mode: 0644]
gpsbabel/ozi.c [new file with mode: 0644]
gpsbabel/reference/ozi.ozi [new file with mode: 0644]

diff --git a/gpsbabel/csv_util.c b/gpsbabel/csv_util.c
new file mode 100644 (file)
index 0000000..4471b7b
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+    Utilities for parsing Comma Seperated Value files (CSV)
+
+    Copyright (C) 2002 Alex Mottram (geo_alexm at cox-internet.com)
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include <ctype.h>
+#include <unistd.h>
+#include "defs.h"
+#include "csv_util.h"
+
+#define MYNAME "CSV_UTIL"
+
+/*********************************************************************/
+/* csv_stringclean() - remove any unwanted characters from string.   */
+/*                     returns MODIFIED string.                      */
+/*     usage: csv_stringclean(stringtoclean, "&,\"")                 */
+/*            (strip out ampersands, commas, and quotes.             */
+/*********************************************************************/
+char *
+csv_stringclean(char *string, const char *chararray) {
+    char * p;
+    char * lp;
+    const char * cp;
+
+    if ((! string) || (! chararray)) {
+        return (string);
+    }
+    
+    /* lp - end of the original string */
+    lp = string;
+    while (*lp) lp++;
+    
+    cp = chararray;
+    while (*cp) {
+
+
+        p = string;
+        while (*p) {
+            if (*cp == *p) {
+                /* we don't want this character! */
+                strncpy(p, p+1, (lp - p));
+            }
+            p++;
+        }
+        cp++;
+    }
+    
+    return (string);
+}
+
+
+/***********************************************************************************/
+/* csv_stringtrim() - trim whitespace and leading and trailing enclosures (quotes) */
+/*                    returns MODIFIED string.                                     */
+/*    usage: csv_stringtrim(string, "\"")                                          */
+/***********************************************************************************/
+char *
+csv_stringtrim(char *string, const char *enclosure)
+{
+    static char *p1 = NULL;
+    char *p2 = NULL;
+    size_t elen;
+
+    if (!string) {
+       return (string);
+    }
+
+    if (!enclosure) {
+       elen = 0;
+    } else {
+       elen = strlen(enclosure);
+    }
+
+    p2 = string;
+
+    /* advance pointer to the end of the string */
+    while ((*p2) && (p2++)) {
+    }
+    p2--;
+
+    /* trim off trailing whitespace */
+    while (isspace(*p2)) {
+       *p2 = '\0';
+       p2--;
+    }
+
+    p1 = string;
+
+    /* advance p1 past any leading whitespace */
+    while (isspace(*p1)) {
+       p1++;
+    }
+
+    /* if we have enclosures, yank them out in pairs */
+    if (elen) {
+       while ((strncmp(p1, enclosure, elen) == 0)
+              && (strncmp(p2, enclosure, elen) == 0)) {
+           *p2 = '\0';
+           p2--;
+           p1++;
+       }
+    }
+
+    return (p1);
+}
+
+/*****************************************************************************/
+/* csv_lineparse() - extract data fields from a delimited string. designed   */
+/*                   to handle quoted and delimited data within quotes.      */
+/*                   returns temporary COPY of delimited data field (use it  */
+/*                   or lose it).                                            */
+/*    usage: p = csv_lineparse(string, ",", "\"", line)  [initial call]      */
+/*           p = csv_lineparse(NULL, ",", "\"", line)    [subsequent calls]  */
+/*****************************************************************************/
+char *
+csv_lineparse(char *stringstart, const char *delimited_by, 
+               const char *enclosed_in, const int line_no)
+{
+    char *sp;
+    static char *p = NULL;
+    static char *tmp = NULL;
+    size_t dlen, elen;
+    int enclosedepth = 0;
+    short int dfound;
+
+    if (!p) {
+       /* first pass thru */
+       p =  stringstart;
+
+       if (!p) {
+           /* last pass out */
+           return (NULL);
+       }
+    }
+
+    if (tmp) {
+       free(tmp);
+       tmp = NULL;
+    }
+
+    /* the beginning of the string we start with (this pass) */
+    sp = p;
+
+    /* length of delimiters and enclosures */
+    dlen = strlen(delimited_by);
+    elen = strlen(enclosed_in);
+
+    dfound = 0;
+
+    while ((*p) && (!dfound)) {
+       if (strncmp(p, enclosed_in, elen) == 0) {
+           if (enclosedepth)
+               enclosedepth--;
+           else
+               enclosedepth++;
+       }
+
+       if ((!enclosedepth) && (strncmp(p, delimited_by, dlen) == 0)) {
+           dfound = 1;
+
+       } else {
+           p++;
+       }
+    }
+
+    /* allocate enough space for this data field */
+    tmp = (char *) calloc((p - sp) + 1, sizeof(char));
+
+    if (!tmp) {
+       fatal(MYNAME ": cannot allocate memory\n");
+    }
+
+    strncpy(tmp, sp, (p - sp));
+
+    if (dfound) {
+       /* skip over the delimited_by */
+       p += dlen;
+    } else {
+       /* end of the line */
+       p = NULL;
+    }
+
+    if (enclosedepth != 0) {
+       fprintf(stderr, "%s: Warning- Unbalanced Field Enclosures (%s) on line %d\n",
+               MYNAME, enclosed_in, line_no);
+    }
+
+    return (tmp);
+}
diff --git a/gpsbabel/csv_util.h b/gpsbabel/csv_util.h
new file mode 100644 (file)
index 0000000..170cc43
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+    Copyright (C) 2002 Alex Mottram (geo_alexm at cox-internet.com)
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+/* function prototypes */
+char *
+csv_stringtrim(char *string, const char *enclosure);
+
+char *
+csv_lineparse(char *stringstart, const char *delimited_by, const char *enclosed_in, const int line_no);
+
+char *
+csv_stringclean(char *string, const char *chararray);
diff --git a/gpsbabel/ozi.c b/gpsbabel/ozi.c
new file mode 100644 (file)
index 0000000..79841f6
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+    OziExplorer Waypoint File Version 1.1 Format (.wpt)
+    Fixed-Length Comma Delimited 
+
+    Contributed to gpsbabel by Alex Mottram (geo_alexm at cox-internet.com)
+
+    As described in Maptech Terrain Navigator Help File.
+    Tested against Terrain Navigator and ExpertGPS import/export .MXF files.
+
+    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include "defs.h"
+#include "csv_util.h"
+#include <ctype.h>
+#include <math.h> /* for floor */
+
+#define MYNAME "OZI"
+
+static FILE *file_in;
+static FILE *file_out;
+
+static void 
+rd_init(const char *fname)
+{
+    file_in = fopen(fname, "r");
+    if (file_in == NULL) {
+       fatal(MYNAME ": Cannot open %s for reading\n", fname);
+    }
+}
+
+static void 
+rd_deinit(void)
+{
+    fclose(file_in);
+}
+
+static void 
+wr_init(const char *fname)
+{
+    file_out = fopen(fname, "w");
+    if (file_out == NULL) {
+       fatal(MYNAME ": Cannot open %s for writing\n", fname);
+    }
+}
+
+static void 
+wr_deinit(void)
+{
+    fclose(file_out);
+}
+
+static void 
+data_read(void)
+{
+    char buff[1024];
+    char *s;
+    waypoint *wpt_tmp;
+    int i;
+    int linecount = 0;
+
+    do {
+        linecount++;
+       memset(&buff, '\0', sizeof(buff));
+       fgets(buff, sizeof(buff), file_in);
+
+       if ((strlen(buff)) && (strstr(buff, ",") != NULL)) {
+
+           wpt_tmp = calloc(sizeof(*wpt_tmp), 1);
+
+           if (wpt_tmp == NULL) {
+               fatal(MYNAME ": cannot allocate memory\n");
+           }
+
+           /* data delimited by commas, possibly enclosed in quotes.  */
+           s = buff;
+           s = csv_lineparse(s, ",", "\"", linecount);
+
+           i = 0;
+           while (s) {
+               switch (i) {
+               case 0:
+                   /* sequence # */
+                   break;
+               case 1:
+                   /* waypoint name */
+                   wpt_tmp->shortname = strdup(s);
+
+                   if (! wpt_tmp->shortname) 
+                       fatal(MYNAME, ": cannot allocate memory\n");
+
+                   csv_stringtrim(wpt_tmp->shortname, "");
+                   break;
+               case 2:
+                   /* degrees latitude */
+                   wpt_tmp->position.latitude.degrees = atof(s);
+                   break;
+               case 3:
+                   /* degrees longitude */
+                   wpt_tmp->position.longitude.degrees = atof(s);
+                   break;
+               case 4:
+                    /* DAYS since 1900 00:00:00 in days.days (5.5) */
+                   wpt_tmp->creation_time = (atof(s) - 25569.0) * 86400.0;                    
+                   break;
+               case 5:
+                   /* icons 0-xx */
+                   break;
+               case 6:
+                   /* unknown - always 1 */
+                   break;
+               case 7:
+                   /* display format options 0-8 */
+                   break;
+               case 8:
+                   /* foreground color (0=black) */
+                   break;
+               case 9:
+                   /* background color (65535=yellow)*/
+                   break;
+               case 10:
+                   /* Description */
+                   wpt_tmp->description = strdup(s);
+
+                   if (! wpt_tmp->description) 
+                       fatal(MYNAME, ": cannot allocate memory\n");
+
+                   wpt_tmp->description = csv_stringtrim(wpt_tmp->description, "");
+
+                   break;
+               case 11:
+                   /* pointer direction 0,1,2,3 bottom,top,left,right */
+                   break;
+               case 12:
+                   /* garmin gps display flags (0-name w/sym, 1-sym only, 2-comment w/symbol */
+                   break;
+               case 13:
+                   /* proximity distance - meters */
+                   break;
+               case 14:
+                   /* altitude in feet */
+                   wpt_tmp->position.altitude.altitude_meters = (atof(s) * .3048);
+                   break;
+               case 15:
+                   /* waypoint text name size */
+                   break;
+               case 16:
+                   /* bold checkbox (1=bold, default 0) */
+                   break;
+               case 17:
+                   /* symbol size - 17 default */
+                   break;
+               default:
+                   /* whoa! nelly */
+                   fprintf (stderr, "%s: Warning: data fields on line %d exceed specification.\n", 
+                       MYNAME, linecount);
+                   break;
+               }
+               i++;
+
+               s = csv_lineparse(NULL, ",", "\"", linecount);
+           }
+           
+           waypt_add(wpt_tmp);
+
+       } else {
+            /* empty line */
+       }
+
+    } while (!feof(file_in));
+}
+
+static void 
+ozi_disp(waypoint * wpt)
+{
+    static int index = 0;
+    double alt_feet;
+    double ozi_time;
+
+    ozi_time = (wpt->creation_time / 86400.0) + 25569.0;
+    alt_feet = (wpt->position.altitude.altitude_meters * 3.2808); 
+    
+    csv_stringclean(wpt->description, ",");
+    csv_stringclean(wpt->shortname, ",");
+
+    index++;
+
+    fprintf(file_out, "%4d,%-14.14s,%11.6f,%11.6f,%011.5f,%3d,%2d,%2d,%10d,%10d,%-40.40s,%2d,%2d,%5d,%7.0f,%2d,%2d,%2d\n", 
+       index, wpt->shortname, wpt->position.latitude.degrees, 
+       wpt->position.longitude.degrees, ozi_time, 0, 1, 3, 0, 65535,
+       wpt->description, 0, 0, 0, alt_feet, 6, 0, 17);
+
+}
+
+static void 
+data_write(void)
+{
+
+    fprintf(file_out, "OziExplorer Waypoint File Version 1.1\n");
+    fprintf(file_out, "WGS 84\n");
+    fprintf(file_out, "Reserved 2\n");
+    fprintf(file_out, "Reserved 3\n");
+
+    waypt_disp_all(ozi_disp);
+}
+
+ff_vecs_t ozi_vecs = {
+    rd_init,
+    wr_init,
+    rd_deinit,
+    wr_deinit,
+    data_read,
+    data_write,
+};
+
diff --git a/gpsbabel/reference/ozi.ozi b/gpsbabel/reference/ozi.ozi
new file mode 100644 (file)
index 0000000..bf7266a
--- /dev/null
@@ -0,0 +1,13 @@
+OziExplorer Waypoint File Version 1.1
+WGS 84
+Reserved 2
+Reserved 3
+   1,GCEBB         ,  35.972033, -87.134700,25569.00000,  0, 1, 3,         0,     65535,Mountain Bike Heaven by susy1313        , 0, 0,    0,      0, 6, 0,17
+   2,GC1A37        ,  36.090683, -86.679550,25569.00000,  0, 1, 3,         0,     65535,The Troll by a182pilot & Family         , 0, 0,    0,      0, 6, 0,17
+   3,GC1C2B        ,  35.996267, -86.620117,25569.00000,  0, 1, 3,         0,     65535,Dive Bomber by JoGPS & family           , 0, 0,    0,      0, 6, 0,17
+   4,GC25A9        ,  36.038483, -86.648617,25569.00000,  0, 1, 3,         0,     65535,FOSTER by JoGPS & Family                , 0, 0,    0,      0, 6, 0,17
+   5,GC2723        ,  36.112183, -86.741767,25569.00000,  0, 1, 3,         0,     65535,Logan Lighthouse by JoGps & Family      , 0, 0,    0,      0, 6, 0,17
+   6,GC2B71        ,  36.064083, -86.790517,25569.00000,  0, 1, 3,         0,     65535,Ganier Cache by Susy1313                , 0, 0,    0,      0, 6, 0,17
+   7,GC309F        ,  36.087767, -86.809733,25569.00000,  0, 1, 3,         0,     65535,Shy's Hill by FireFighterEng33          , 0, 0,    0,      0, 6, 0,17
+   8,GC317A        ,  36.057500, -86.892000,25569.00000,  0, 1, 3,         0,     65535,GittyUp by JoGPS / Warner Parks         , 0, 0,    0,      0, 6, 0,17
+   9,GC317D        ,  36.082800, -86.867283,25569.00000,  0, 1, 3,         0,     65535,Inlighting by JoGPS / Warner Parks      , 0, 0,    0,      0, 6, 0,17